package com.zb.mobile.user.controller;

import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.zb.annotation.SystemLog;
import com.zb.constant.LogConstant;
import com.zb.constant.OperationLogModuleType;
import com.zb.constant.OperationLogType;
import com.zb.entity.AccounLoginInfo;
import com.zb.entity.ZjUserSet;
import com.zb.exception.SMSException;
import com.zb.exception.VendorIdentifierException;
import com.zb.mobile.UserMobileInfoVo;
import com.zb.mobile.user.service.ConUserMobileCodeService;
import com.zb.mobile.user.service.ConUserMobileService;
import com.zb.redis.RedisUserLoginTokenUtil;
import com.zb.result.Result;
import com.zb.service.ZjUserContactService;
import com.zb.service.ZjUserService;
import com.zb.service.ZjUserSetService;
import com.zb.stp.StpUserUtil;
import com.zb.utils.TokenNetworkUtil;
import com.zb.utils.TokenUserUtil;
import com.zb.utils.VerificUtil;
import com.zb.utils.ZbManager;
import com.zb.vo.UserContactVo;
import com.zb.vo.UserLoginVo;
import com.zb.vo.UserPasswordVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.security.auth.login.LoginException;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author WEN
 * @Date 2023/10/31 0031
 **/
@Api(tags = "用户报单移动端客户类接口")
@RestController
@RequestMapping("/mobile/user")
public class UserLoginController {
    @Resource
    private ConUserMobileService conUserMobileService;
    @Resource
    private ZjUserService userService;
    @Resource
    private ZjUserContactService userContactService;
    @Resource
    private ZjUserSetService userSetService;

    @ApiOperation("查询客户移动端是否必须登录")
    @GetMapping("/getMobileUserHasLogin")
    public Result getMobileUserHasLogin(HttpServletRequest request) throws VendorIdentifierException {
        Long custAccId = TokenUserUtil.getCustAccIdByMobildUserCustCode(request);
        ZjUserSet userSet = userSetService.getById(custAccId);
        return Result.success().data("userMobileHasLogin", null != userSet && userSet.getMobileHasLogin());
    }

    @ApiOperation("校验手机号是否注册")
    @GetMapping("/checkPhone")
    public Result isRegisterPhone(HttpServletRequest request, @RequestParam @ApiParam(value = "手机号", required = true) String phone) throws VendorIdentifierException {
        Assert.isTrue(VerificUtil.phoneVerific(phone), "手机号格式错误");
        Long custAccId = TokenUserUtil.getCustAccIdByMobildUserCustCode(request);
        boolean registerPhone = userService.isRegisterPhone(custAccId, phone);
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("registerPhone", registerPhone);
        return Result.success().data("row", resultMap);
    }

    @ApiOperation("登录")
    @PostMapping("/login")
    public Result login(HttpServletRequest request, @RequestBody @Valid UserLoginVo loginVo) throws VendorIdentifierException, LoginException, SMSException {
        Long custAccId = TokenUserUtil.getCustAccIdByMobildUserCustCode(request);
        return Result.success("登录成功").data("row", conUserMobileService.login(custAccId, loginVo));
    }

    @ApiOperation("刷新登录Token")
    @GetMapping("/refreshToken")
    public Result refreshToken(@RequestParam @ApiParam(value = "刷新token", required = true) String refreshToken) throws LoginException {
        return Result.success("token刷新成功").data("row", conUserMobileService.refreshToken(refreshToken));
    }

    @ApiOperation("退出登录")
    @GetMapping("/logout")
    public Result logout(HttpServletRequest request) {
        String accessToken = TokenUserUtil.getToken(request);
        RedisUserLoginTokenUtil.removeAllTokenByAccessToken(accessToken);
        StpUserUtil.logoutByTokenValue(accessToken);
        return Result.success("退出登录成功");
    }

    @ApiOperation("注销账号")
    @GetMapping("/cancelAccount")
    public Result cancelAccount(HttpServletRequest request) {
        AccounLoginInfo loginInfo = TokenUserUtil.getAccountLoginInfo(request);
        conUserMobileService.cancelAccount(loginInfo);
        return Result.success("账号注销成功！");
    }

    @ApiOperation("修改登录页面的密码")
    @PutMapping("/logInRestPwd")
    public Result logInRestPwd(HttpServletRequest request, @RequestBody @Valid UserPasswordVo userPasswordVo) throws VendorIdentifierException, SMSException {
        Long custAccId = TokenUserUtil.getCustAccIdByMobildUserCustCode(request);
        userService.logInRestPwd(custAccId, userPasswordVo);
        return Result.success("密码修改成功");
    }

    @ApiOperation("获取当前客户登录信息")
    @GetMapping("/getUerDetail")
    public Result getUerDetail(HttpServletRequest request) {
        Long userId = TokenUserUtil.getAccountIdByToken(request);
        return Result.success().data(conUserMobileService.getUerDetail(userId));
    }

    @SystemLog(moduleType = OperationLogModuleType.USER_MODULE_TYPE, type = OperationLogType.UPDATE, empType = LogConstant.SYSTEM_LOG_EMP_TYPE_2, remark = "修改密码", addLogParam = false)
    @ApiOperation("修改密码")
    @PutMapping("/updatePwd")
    public Result updatePwd(HttpServletRequest request, @RequestBody @Valid UserPasswordVo userPasswordVo) throws SMSException {
        Long userId = TokenUserUtil.getAccountIdByToken(request);
        userService.updatePwd(userId, userPasswordVo);
        return Result.success("修改密码成功");
    }

    @ApiOperation("查询是否已绑定手机号")
    @GetMapping("/isBindingPhone")
    public Result isBindingPhone(HttpServletRequest request) {
        Long userId = TokenUserUtil.getAccountIdByToken(request);
        boolean bindingPhone = userService.isBindingPhone(userId);
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("bindingPhone", bindingPhone);
        return Result.success().data("row", resultMap);
    }

    @SystemLog(moduleType = OperationLogModuleType.USER_MODULE_TYPE, type = OperationLogType.UPDATE, empType = LogConstant.SYSTEM_LOG_EMP_TYPE_2, remark = "绑定或换绑手机号", addLogParam = false)
    @ApiOperation("绑定或换绑手机号")
    @PutMapping("/bindingPhone")
    public Result bindingPhone(HttpServletRequest request, @RequestParam @ApiParam(value = "手机号", required = true) String phone,
                               @RequestParam @ApiParam(value = "验证码", required = true) String code) throws SMSException {
        Assert.isTrue(VerificUtil.phoneVerific(phone), "手机号格式错误");
        Assert.isTrue(StringUtils.isNotBlank(code), "验证码不能为空");

        Long userId = TokenUserUtil.getAccountIdByToken(request);
        userService.bindingPhone(userId, phone, code);
        return Result.success("绑定手机成功");
    }

    @SystemLog(moduleType = OperationLogModuleType.USER_MODULE_TYPE, type = OperationLogType.UPDATE, empType = LogConstant.SYSTEM_LOG_EMP_TYPE_2, remark = "新增或修改联系人地址", addLogParam = false)
    @ApiOperation("新增或修改联系人地址")
    @PostMapping("/saveUserContactAddress")
    public Result saveUserContactAddress(HttpServletRequest request, @RequestBody @Valid UserContactVo userContactVo) {
        AccounLoginInfo logintInfo = TokenUserUtil.getAccountLoginInfo(request);
        userService.saveUserContactAddress(logintInfo, userContactVo);
        return Result.success(null == userContactVo.getId()? "新增地址成功" : "修改地址成功");
    }

    @SystemLog(moduleType = OperationLogModuleType.USER_MODULE_TYPE, type = OperationLogType.UPDATE, empType = LogConstant.SYSTEM_LOG_EMP_TYPE_2, remark = "删除联系人地址", addLogParam = false)
    @ApiOperation("删除联系人地址")
    @DeleteMapping("/deleteUserContactAddress/{id}")
    public Result deleteUserContactAddress(@PathVariable @ApiParam(value = "联系人ID") Long id) {
        userContactService.deleteUserContactAddress(id);
        return Result.success("删除联系人地址成功");
    }

    @SystemLog(moduleType = OperationLogModuleType.USER_MODULE_TYPE, type = OperationLogType.UPDATE, empType = LogConstant.SYSTEM_LOG_EMP_TYPE_2, remark = "编辑个人资料", addLogParam = false)
    @ApiOperation("编辑个人资料")
    @PutMapping("/updateUserInfo")
    public Result updateUserInfo(HttpServletRequest request, @RequestBody UserMobileInfoVo userMobileInfoVo) {
        Long userId = TokenUserUtil.getAccountIdByToken(request);
        userService.updateMobileUserInfo(userId, userMobileInfoVo);
        return Result.success("个人资料编码成功");
    }

}
